package com.gurumades.jsonform.client.presenter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.gurumades.jsonform.client.FormsMessages;
import com.gurumades.jsonform.client.IFormController;
import com.gurumades.jsonform.client.JSONUtils;
import com.gurumades.jsonform.client.constants.AppMessages;
import com.gurumades.jsonform.client.forms.FormItemViewIF;

public class JsonFormPresenter {
	public interface Display {
		public JSONObject getDisplayObject();
		public HashMap<String, JSONObject> getDisplayFields();
		public void setData(JSONValue displayFieldsArray, JSONObject displayObject, String userRole);
		Widget asWidget();
		HashMap<String, FormItemViewIF> getFormItems();
	}
	
	public interface FormItemError{
		public String getMessage();
		public String getFieldID();
	}
	
	private FormsMessages MESSAGES = FormsMessages.Util.instance();
	
	private JSONObject displayObject;
	private Display display;
	private IFormController appController;
	
	private String formID;
	
	private List<FormItemError> errors = new ArrayList<FormItemError>();
	 
	public JsonFormPresenter(Display display, JSONObject displayObject, IFormController controller, String formID){
		try {
			this.display = display;
			this.displayObject = displayObject;
			appController = controller;
			this.formID = formID;
		} catch (Exception ex) {
			Window.alert("constructor" + ex.getMessage());
		}
	}
	

	private void fetchDisplayFields(){
		JSONObject displayFields = appController.getDisplayFields(formID).isObject();
		
		if (displayFields == null) {
			return;
		}

		
		display.setData(displayFields.get("line"), displayObject, appController.getUserRole());
		bind();
	}
	

	public void go(HasWidgets container, IFormController appController) {
		try {			
			this.appController = appController;
			container.clear();
			container.add(display.asWidget());
			this.fetchDisplayFields();
		} catch (Exception ex) {
			Window.alert("go" + ex.getLocalizedMessage());
		}
	}

	/**
	 * Used to bind handers to their methods
	 */
	@SuppressWarnings("deprecation")
	public void bind() {
		
	}


	public ArrayList<JSONObject> flush() {
		HashMap<String, FormItemViewIF> items = display.getFormItems();
		HashMap<String, JSONObject> settings = display.getDisplayFields();
		
		errors.clear();
		
		Set<String> keys = items.keySet();
		
		ArrayList<JSONObject> result = new ArrayList<JSONObject>();
		
		for (String string : keys) {
			JSONObject row = settings.get(string);
			FormItemViewIF item = items.get(string);
			
			boolean isRequired = JSONUtils.getBoolean("required", row);
			if (isRequired && item.isValueEmpty()) {
				String error = MESSAGES.required_field_errorl(JSONUtils.getString("name", row));
				item.setError(true, error);
				
				errors.add(new FormItemErrorImpl(error, string));
			}else{
				item.setError(false, null);
				
				if (!item.isValueEmpty()) {
					JSONObject value = item.getValue();
					JSONObject toAdd = new JSONObject();
					toAdd.put(string, value);
					result.add(toAdd);
				}
				
			}
		}
		return result;
	}
	
	
	public static class FormItemErrorImpl implements FormItemError{
		String message;
		String fieldID;
		
		public FormItemErrorImpl(String message, String fieldID) {
			super();
			this.message = message;
			this.fieldID = fieldID;
		}
		
		@Override
		public String getMessage() {
			return message;
		}
		public void setMessage(String message) {
			this.message = message;
		}
		@Override
		public String getFieldID() {
			return fieldID;
		}
		public void setFieldID(String fieldID) {
			this.fieldID = fieldID;
		}
		
		
	}
}
